package controller

import (
	"gin-service/lib/GinSrv/GinResp"
	"gin-service/lib/GinSrv/GinRouter"
	"gin-service/lib/GormSrv"
	"gin-service/lib/GormSrv/model"
	"gin-service/utils"
	"github.com/gin-gonic/gin"
	"github.com/jinzhu/gorm"
)

func ErcUserController(router GinRouter.Router) {
	router.InitRouter()
	response := new(GinResp.RespImpl)

	router.Get("/queryClientList", func(ctx *gin.Context) {
		username := ctx.Query("username")

		selectColumn := []string{"user_code", "username", "contact", "phone", "remark"}
		query := GormSrv.GDB().Table("tbl_user").Select(selectColumn)

		if username != "" {
			query = query.Where("username like ?", "%" + username + "%")
		}

		offset := utils.STI(ctx.DefaultQuery("offset", "0"))
		limit := utils.STI(ctx.DefaultQuery("limit", "-1"))
		query = query.Offset(offset).Limit(limit)

		returnData := map[string]interface{}{}
		pagingQuery := ctx.Query("paging_query")
		if utils.STB(pagingQuery) {
			var count int
			query.Count(&count)
			returnData["count"] = count
		}

		type UserQuery struct {
			UserCode string `json:"user_code"`
			Username string `json:"username"`
			Contact string `json:"contact"`
			Phone string `json:"phone"`
			Remark string `json:"remark"`
		}
		var userList []UserQuery
		query.Find(&userList)
		returnData["rows"] = userList

		response.DataResp(ctx, returnData)
	})

	router.Get("/queryClientList2", func(ctx *gin.Context) {
		username := ctx.Query("username")

		selectColumn := []string{"user_code", "username", "contact", "phone", "remark"}
		resultData := map[string]interface{}{}

		type UserQuery struct {
			UserCode string `json:"user_code"`
			Username string `json:"username"`
			Contact string `json:"contact"`
			Phone string `json:"phone"`
			Remark string `json:"remark"`
		}
		var userList []UserQuery

		GinRouter.GormQuery(ctx, "tbl_user", selectColumn, resultData, func(subQuery *gorm.DB) *gorm.DB {
			if username != "" {
				return subQuery.Where("username like ?", "%" + username + "%")
			} else {
				return subQuery
			}
		}).Find(&userList)

		resultData["rows"] = userList

		response.DataResp(ctx, resultData)
	})

	router.Get("/queryBindClient", func(ctx *gin.Context) {
		userCode := ctx.Query("userCode")
		clientUserCode := ctx.Query("clientUserCode")
		clientType := utils.STI(ctx.Query("clientType"))

		if userCode == "" {

		}

		if userCode == "" || clientUserCode == "" || clientType == 0 {
			response.DataResp(ctx, []interface{}{})
			return
		}

		queryString :=
		 	`select
				cur.user_code, cur.username, cur.contact, cur.phone, cur.remark
				from tbl_user_client ucr
				left join tbl_user cur
				on cur.user_id = ucr.client_user_id
				left join tbl_user usr
				on usr.user_id = ucr.user_id
				where true`

		replacement := make([]interface{}, 0)

		if userCode != "" {
			queryString += ` and usr.user_code = ?`
			replacement = append(replacement, userCode)
		}

		if clientUserCode != "" {
			queryString += ` and usr.user_code = ?`
			replacement = append(replacement, userCode)

			queryString += ` and cur.user_code = ?`
			replacement = append(replacement, clientUserCode)
		}

		queryString += ` and usr.user_code = ?`
		replacement = append(replacement, userCode)

		queryString += ` and cur.user_code = ?`
		replacement = append(replacement, clientUserCode)

		queryString += ` and ucr.client_type = ?`
		replacement = append(replacement, clientType)

		type UserQuery struct {
			UserCode string `json:"user_code"`
			Username string `json:"username"`
			Contact string `json:"contact"`
			Phone string `json:"phone"`
			Remark string `json:"remark"`
		}
		var userList []UserQuery
		GormSrv.GDB().Raw(queryString, replacement...).Scan(&userList)

		response.DataResp(ctx, userList)
	})

	router.Post("/createClient", func(ctx *gin.Context) {
		type Payload struct {
			ClientCode string
			DomainCode string
			Username string
			Contact string
			Phone string
			Remark string
		}
		type ReqBody struct {
			Header interface{}
			Data Payload
		}

		var reqBody ReqBody
		GinRouter.ThrowError(ctx.BindJSON(&reqBody))

		if reqBody.Data.ClientCode == "" {
			panic("clientCode missing")
		}

		if reqBody.Data.DomainCode == "" {
			panic("domainCode missing")
		}

		if reqBody.Data.Username == "" {
			panic("username missing")
		}

		userCode := reqBody.Data.ClientCode + reqBody.Data.DomainCode

		var result *gorm.DB
		var userData model.User
		GormSrv.GDB().Where(&model.User{UserCode: userCode}).First(&userData)
		if userData.UserId > 0 {
			userData.Username = reqBody.Data.Username
			userData.Remark = reqBody.Data.Remark
			userData.Contact = reqBody.Data.Contact
			userData.Phone = reqBody.Data.Phone
			userData.Remark = reqBody.Data.Remark
			result = GormSrv.GDB().Save(&userData)
			GormSrv.ThrowDBError(result)
		} else {
			userData := model.User{
				UserCode: userCode,
				Username: reqBody.Data.Username,
				Contact: reqBody.Data.Contact,
				Phone: reqBody.Data.Phone,
				Remark: reqBody.Data.Remark,
			}
			result = GormSrv.GDB().Create(&userData)
			GormSrv.ThrowDBError(result)
		}

		response.DataResp(ctx, result)
	})

	router.Post("/createClientBatch", func(ctx *gin.Context) {
		type Payload struct {
			ClientCode string
			DomainCode string
			Username string
			Contact string
			Phone string
			Remark string
		}
		type PayloadList struct {
			ClientList []Payload
		}
		type ReqBody struct {
			Header interface{}
			Data PayloadList
		}

		var reqBody ReqBody
		GinRouter.ThrowError(ctx.BindJSON(&reqBody))

		for _, item := range reqBody.Data.ClientList {
			userCode := item.ClientCode + item.DomainCode

			var result *gorm.DB
			var userData model.User
			GormSrv.GDB().Where(&model.User{UserCode: userCode}).First(&userData)
			if userData.UserId > 0 {
				userData.Username = item.Username
				userData.Remark = item.Remark
				userData.Contact = item.Contact
				userData.Phone = item.Phone
				userData.Remark = item.Remark
				result = GormSrv.GDB().Save(&userData)
				GormSrv.ThrowDBError(result)
			} else {
				userData := model.User{
					UserCode: userCode,
					Username: item.Username,
					Contact: item.Contact,
					Phone: item.Phone,
					Remark: item.Remark,
				}
				result = GormSrv.GDB().Create(&userData)
				GormSrv.ThrowDBError(result)
			}
		}

		response.DataResp(ctx, nil)
	})

	router.Post("/bindUserClient", func(ctx *gin.Context) {
		type Payload struct {
			UserCode string
			ClientCode string
			ClientType int
			OriginClientCode string
		}
		type ReqBody struct {
			Header interface{}
			Data Payload
		}

		var reqBody ReqBody
		GinRouter.ThrowError(ctx.BindJSON(&reqBody))

		if reqBody.Data.UserCode == "" {
			panic("userCode missing")
		}

		if reqBody.Data.ClientCode == "" {
			panic("clientCode missing")
		}

		if reqBody.Data.ClientType == 0 {
			panic("bindType missing")
		}

		if reqBody.Data.UserCode == reqBody.Data.ClientCode {
			panic("can not select yourself")
		}

		//查询主体的信息
		var userData model.User
		GormSrv.GDB().Where("user_code = ?", reqBody.Data.UserCode).First(&userData)
		if userData.UserId == 0 {
			panic("pivot user not found")
		}

		//查询对应客户的信息
		var clientData model.User
		GormSrv.GDB().Where("user_code = ?", reqBody.Data.ClientCode).First(&clientData)
		if clientData.UserId == 0 {
			panic("pivot client not found")
		}

		//查询主体和客户是否绑定关系
		queryMap := map[string]interface{}{
			"user_id": userData.UserId,
			"client_user_id": clientData.UserId,
			"client_type": reqBody.Data.ClientType,
		}
		var queryCount int
		GormSrv.GDB().Where(queryMap).Find(&model.UserClient{}).Count(&queryCount)

		if queryCount > 0 {
			panic("pivot client already bind")
		}

		//删除原来的客户关系
		if reqBody.Data.OriginClientCode != "" && reqBody.Data.OriginClientCode != reqBody.Data.ClientCode {
			var originClientData model.User
			GormSrv.GDB().Where("user_code = ?", reqBody.Data.OriginClientCode).First(&originClientData)
			if originClientData.UserId == 0 {
				panic("pivot origin client not found")
			}

			queryMap := map[string]interface{}{
				"user_id": userData.UserId,
				"client_user_id": originClientData.UserId,
				"client_type": reqBody.Data.ClientType,
			}
			GormSrv.GDB().Unscoped().Where(queryMap).Delete(&model.UserClient{})
		}

		//绑定客户关系
		userClientForm := model.UserClient{
			UserId: userData.UserId,
			ClientUserId: clientData.UserId,
			ClientType: reqBody.Data.ClientType,
		}

		GormSrv.GDB().Create(&userClientForm)

		response.DataResp(ctx, userClientForm)
	})

	router.Post("/insert", func(ctx *gin.Context) {
		var userForm model.User
		err := ctx.BindJSON(&userForm)
		if err != nil {
			panic(err.Error())
		}

		if userForm.UserCode == "" {
			panic("user_code missing")
		}

		if userForm.Username == "" {
			panic("username missing")
		}

		result := GormSrv.GDB().Create(&userForm)
		GormSrv.ThrowDBError(result)

		response.DataResp(ctx, result)
	})

	router.Put("/update", func(ctx *gin.Context) {
		userId := ctx.Query("userId")

		updateUser := model.User{}
		GinRouter.ThrowError(ctx.BindJSON(&updateUser))

		userData := &model.User{}
		db := GormSrv.GDB().Model(&userData).Where("user_id = ?", userId)

		if updateUser.UserCode != "" {
			db.Update("user_code", updateUser.UserCode)
		}
		if updateUser.Username != "" {
			db.Update("username", updateUser.Username)
		}

		response.DataResp(ctx, db.RowsAffected)
	})

	router.Put("/update/:userId", func(ctx *gin.Context) {
		userId := ctx.Param("userId")

		updateUser := model.User{}
		GinRouter.ThrowError(ctx.BindJSON(&updateUser))

		findUser := model.User{}
		GormSrv.GDB().First(&findUser, userId)
		GormSrv.GDB().Model(&findUser).Updates(&updateUser)

		response.DataResp(ctx, findUser)
	})

	router.Delete("/delete", func(ctx *gin.Context) {
		userId := ctx.Query("userId")
		if userId == "" {
			panic("userId missing")
		}

		result := GormSrv.GDB().Unscoped().Delete(&model.User{}, userId)
		GormSrv.ThrowDBError(result)

		response.DataResp(ctx, result)
	})

	router.Delete("/deleteAll", func(ctx *gin.Context) {
		result := GormSrv.GDB().Unscoped().Where("name is null").Delete(&model.User{})
		GormSrv.ThrowDBError(result)

		response.DataResp(ctx, result)
	})
}
